home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 038a / ike.zip / ICO.C < prev    next >
C/C++ Source or Header  |  1991-01-08  |  19KB  |  537 lines

  1. /*===========================================================================*/
  2. /*                                                                           */
  3. /* File    : ICO.C                                                           */
  4. /*                                                                           */
  5. /* Purpose : Main routine for the IKE icon editor.                           */
  6. /*                                                                           */
  7. /* History :                                                                 */
  8. /*                                                                           */
  9. /* (C) Copyright 1991 Marc Adler/Magma Systems     All Rights Reserved       */
  10. /*===========================================================================*/
  11.  
  12. #include <memory.h>
  13. #include <string.h>
  14. #include <windows.h>
  15. #include "ico.h"
  16.  
  17. HWND   hWndMain;
  18. HWND   hWndEdit;
  19. HWND   hWndDebug;
  20. HWND   hWndActualImage;
  21. HANDLE hInst = 0;
  22. HANDLE hAccTable;
  23.  
  24. ICONHEADER IconHeader;
  25. ICONDIRECTORY IconDir;
  26.  
  27. ICONINFO IconInfo =
  28. {
  29.   NULL, NULL, 0, '\0'
  30. };
  31.  
  32. BYTE rgb[16][3] =
  33. { /* B     G     R   */
  34.   { 0x00, 0x00, 0x00 },
  35.   { 0x00, 0x00, 0x80 },
  36.   { 0x00, 0x80, 0x00 },
  37.   { 0x00, 0x80, 0x80 },
  38.   { 0x80, 0x00, 0x00 },
  39.   { 0x80, 0x00, 0x80 },
  40.   { 0x80, 0x80, 0x00 },
  41.   { 0x80, 0x80, 0x80 },
  42.   { 0xC0, 0xC0, 0xC0 },
  43.   { 0x00, 0x00, 0xFF },
  44.   { 0x00, 0xFF, 0x00 },
  45.   { 0x00, 0xFF, 0xFF },
  46.   { 0xFF, 0x00, 0x00 },
  47.   { 0xFF, 0x00, 0xFF },
  48.   { 0xFF, 0xFF, 0x00 },
  49.   { 0xFF, 0xFF, 0xFF }
  50. };
  51.  
  52.  
  53.  
  54. /****************************************************************************/
  55. /*                                                                          */
  56. /* Function : WinMain()                                                     */
  57. /*                                                                          */
  58. /* Purpose  : Entry point for a Windows app.                                */
  59. /*                                                                          */
  60. /* Returns  :                                                               */
  61. /*                                                                          */
  62. /****************************************************************************/
  63. int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  64.   HANDLE hInstance;
  65.   HANDLE hPrevInstance;
  66.   LPSTR lpCmdLine;
  67.   int nCmdShow;
  68. {
  69.   HWND hWnd;
  70.   MSG  msg;
  71.   char szFileName[80];
  72.  
  73.   if (!hPrevInstance)        /* Has application been initialized? */
  74.     if (!ICOViewInit(hInstance))
  75.       return (NULL);        /* Exits if unable to initialize     */
  76.   hInst = hInstance;        /* Saves the current instance         */
  77.  
  78.   /*
  79.     Create the main window.
  80.   */
  81.   hWnd = CreateWindow("ICOView",
  82.               "ICOView",
  83.               WS_OVERLAPPEDWINDOW,
  84.               CW_USEDEFAULT,
  85.               CW_USEDEFAULT,
  86. #ifdef DEBUG
  87.               600,
  88. #else
  89.                       520,
  90. #endif
  91.               424,
  92.               NULL,
  93.               NULL,
  94.               hInstance,
  95.               NULL);
  96.   if (!(hWndMain = hWnd))
  97.     return (NULL);
  98.  
  99. #ifdef DEBUG
  100.   /*
  101.     Create a debugging window.
  102.   */
  103.   hWndDebug = CreateWindow("ICODbg",
  104.               "ICODbg",
  105.               WS_OVERLAPPEDWINDOW | WS_CHILD | 
  106.                       WS_VISIBLE | WS_CLIPSIBLINGS,
  107.               280, 0, 400, 400,
  108.               hWnd,
  109.               16,
  110.               hInstance,
  111.               NULL);
  112. #endif
  113.  
  114.  
  115.   /*
  116.     Create the icon editing window
  117.   */
  118.   hWndEdit = CreateWindow("IconEdit",
  119.                     (LPSTR) "Edit",
  120.                   WS_CHILD | WS_BORDER | WS_VISIBLE,
  121.                   5, 2,
  122.                           32*8 + 2*GetSystemMetrics(SM_CXBORDER),
  123.                           32*8 + 2*GetSystemMetrics(SM_CYBORDER),
  124.                   hWnd,
  125.                   1,
  126.                   hInstance,
  127.                   (LPSTR) NULL);
  128.   if (!hWndEdit)
  129.   {
  130.     MessageBox(hWnd, "Can't create hWndEdit", NULL, MB_OK);
  131.     return NULL;
  132.   }
  133.  
  134.  
  135.   /*
  136.     Create the window which will hold the actual icom image (32x32)
  137.   */
  138.   hWndActualImage = CreateWindow("IconImage",
  139.                            (LPSTR) NULL,
  140.                           WS_CHILD | WS_BORDER | WS_VISIBLE,
  141.                           300, 100,
  142.                                   32 + 2*GetSystemMetrics(SM_CXBORDER),
  143.                                   32 + 2*GetSystemMetrics(SM_CYBORDER),
  144.                           hWnd,
  145.                           2,
  146.                           hInstance,
  147.                           (LPSTR) NULL);
  148.   if (!hWndActualImage)
  149.   {
  150.     MessageBox(hWnd, "Can't create hWndActualImage", NULL, MB_OK);
  151.     return NULL;
  152.   }
  153.  
  154.   /*
  155.     Initialize the toolbox
  156.   */
  157.   ToolboxInit(hWndMain);
  158.  
  159.   /*
  160.     The Paste option is initially disabled since there is nothing in
  161.     the paste buffer. (An enhancement would be to make the paste buffer
  162.     shared between instances.)
  163.   */
  164.   EnableMenuItem(GetMenu(hWndMain), IDM_PASTE, 
  165.                  MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  166.  
  167.   /*
  168.     Create a blank icon to start off with.
  169.   */
  170.   NewIcon();
  171.  
  172.   /*
  173.     Read in any icon file which may have been passed on the command line.
  174.   */
  175.   if (lpCmdLine && *lpCmdLine)
  176.   {
  177.     lstrcpy(szFileName, lpCmdLine);
  178.     if (strchr(szFileName, '.') == NULL)
  179.       strcat(szFileName, ".ico");
  180.     ICORead(hWndEdit, szFileName);
  181.   }
  182.  
  183.   /*
  184.     Main message loop...
  185.   */
  186.   while (GetMessage(&msg, NULL, NULL, NULL))
  187.   {
  188.     TranslateMessage(&msg);
  189.     DispatchMessage(&msg);
  190.   }
  191.  
  192.   return (msg.wParam);
  193. }
  194.  
  195.  
  196.  
  197. /****************************************************************************/
  198. /*                                                                          */
  199. /* Function : ICOViewInit()                                                 */
  200. /*                                                                          */
  201. /* Purpose  : Registers all of the classes used by the icon editor.         */
  202. /*                                                                          */
  203. /* Returns  : TRUE if successful, FALSE if not.                             */
  204. /*                                                                          */
  205. /****************************************************************************/
  206. BOOL ICOViewInit(hInstance)
  207.   HANDLE hInstance;
  208. {
  209.   HANDLE hMemory;
  210.   WNDCLASS *pWndClass;
  211.   BOOL bSuccess;
  212.  
  213.   hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
  214.  
  215.   pWndClass = (PWNDCLASS) LocalLock(hMemory);
  216.   pWndClass->hCursor       = LoadCursor(NULL, IDC_ARROW);
  217.   pWndClass->hIcon         = LoadIcon(hInstance, "IKE");
  218.   pWndClass->lpszMenuName  = (LPSTR) "IconEdit";
  219.   pWndClass->lpszClassName = (LPSTR) "ICOView";
  220.   pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  221.   pWndClass->hInstance     = hInstance;
  222.   pWndClass->style         = NULL;
  223.   pWndClass->lpfnWndProc   = ICOViewWndProc;
  224.   bSuccess = RegisterClass(pWndClass);
  225.   if (!bSuccess)
  226.     return FALSE;
  227.  
  228.   pWndClass->hCursor       = (HICON) NULL;
  229.   pWndClass->hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  230.   pWndClass->lpszMenuName  = (LPSTR) NULL;
  231.   pWndClass->lpszClassName = (LPSTR) "IconEdit";
  232.   pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  233.   pWndClass->hInstance     = hInstance;
  234.   pWndClass->style         = NULL;
  235.   pWndClass->lpfnWndProc   = ICOEditWndProc;
  236.   bSuccess = RegisterClass(pWndClass);
  237.   if (!bSuccess)
  238.     return FALSE;
  239.  
  240.   pWndClass->hCursor       = LoadCursor(NULL, IDC_ARROW);
  241.   pWndClass->hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  242.   pWndClass->lpszMenuName  = (LPSTR) NULL;
  243.   pWndClass->lpszClassName = (LPSTR) "IconImage";
  244.   pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  245.   pWndClass->hInstance     = hInstance;
  246.   pWndClass->style         = NULL;
  247.   pWndClass->lpfnWndProc   = ICOImageWndProc;
  248.   bSuccess = RegisterClass(pWndClass);
  249.   if (!bSuccess)
  250.     return FALSE;
  251.  
  252.   pWndClass->hCursor       = LoadCursor(NULL, IDC_ARROW);
  253.   pWndClass->hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  254.   pWndClass->lpszMenuName  = (LPSTR) NULL;
  255.   pWndClass->lpszClassName = (LPSTR) "ToolBox";
  256.   pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  257.   pWndClass->hInstance     = hInstance;
  258.   pWndClass->style         = NULL;
  259.   pWndClass->lpfnWndProc   = ToolBoxWndProc;
  260.   pWndClass->cbWndExtra    = sizeof(HANDLE);
  261.   bSuccess = RegisterClass(pWndClass);
  262.   if (!bSuccess)
  263.     return FALSE;
  264.  
  265. #ifdef DEBUG
  266.   pWndClass->hCursor       = (HICON) NULL;
  267.   pWndClass->hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  268.   pWndClass->lpszMenuName  = (LPSTR) NULL;
  269.   pWndClass->lpszClassName = (LPSTR) "IcoDbg";
  270.   pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  271.   pWndClass->hInstance     = hInstance;
  272.   pWndClass->style         = NULL;
  273.   pWndClass->lpfnWndProc   = ICODebugWndProc;
  274.   bSuccess = RegisterClass(pWndClass);
  275.   if (!bSuccess)
  276.     return FALSE;
  277. #endif
  278.  
  279.   LocalUnlock(hMemory);
  280.   LocalFree(hMemory);
  281.   return bSuccess;
  282. }
  283.  
  284.  
  285. /****************************************************************************/
  286. /*                                                                          */
  287. /* Function : NewIcon()                                                     */
  288. /*                                                                          */
  289. /* Purpose  : Initializes a brand new icon.                                 */
  290. /*                                                                          */
  291. /* Returns  : Nothing.                                                      */
  292. /*                                                                          */
  293. /****************************************************************************/
  294. VOID PASCAL NewIcon(void)
  295. {
  296.   LPSTR lpBits;
  297.   LPBITMAPINFO lpbmi;
  298.  
  299.   /*
  300.     Set up the icon header
  301.   */
  302.   IconHeader.icoReserved      = 0;
  303.   IconHeader.icoResourceType  = 1;
  304.   IconHeader.icoResourceCount = 1;
  305.  
  306.   /*
  307.     Set up a directory entry for a single icon
  308.   */
  309.   IconDir.Width        = 32;
  310.   IconDir.Height       = 32;
  311.   IconDir.ColorCount   = 16;
  312.   IconDir.bReserved1   = 0;
  313.   IconDir.bReserved2   = 0;
  314.   IconDir.bReserved3   = 0;
  315.   IconDir.icoDIBSize   = 744;
  316.   IconDir.icoDIBOffset = 22;
  317.  
  318.   /*
  319.     Set up the icon info structure
  320.   */
  321.   if (IconInfo.hBitmapBits)
  322.     GlobalFree(IconInfo.hBitmapBits);
  323.   if (IconInfo.hBitmapInfo)
  324.     GlobalFree(IconInfo.hBitmapInfo);
  325.   IconInfo.hIcon         = NULL;
  326.   IconInfo.hBitmapBits   = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 32L*32L);
  327.   IconInfo.fFlags        = 0;
  328.   IconInfo.szFilename[0] = '\0';
  329.  
  330.   /*
  331.     The initial pixmap contains all FF's (ie - it's all white)
  332.   */
  333.   lpBits = GlobalLock(IconInfo.hBitmapBits);
  334.   _fmemset(lpBits, 0xFF, 32*32);
  335.   GlobalUnlock(IconInfo.hBitmapBits);
  336.  
  337.   IconInfo.hBitmapInfo = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, 
  338.           (DWORD) sizeof(BITMAPINFOHEADER) + 16*sizeof(RGBQUAD));
  339.   lpbmi = (LPBITMAPINFO) GlobalLock(IconInfo.hBitmapInfo);
  340.   lpbmi->bmiHeader.biSize          = (long) sizeof(BITMAPINFOHEADER);
  341.   lpbmi->bmiHeader.biWidth         = IconDir.Width;
  342.   lpbmi->bmiHeader.biHeight        = IconDir.Height;
  343.   lpbmi->bmiHeader.biPlanes        = 1;
  344.   lpbmi->bmiHeader.biBitCount      = ColorCountToPlanes(IconDir.ColorCount);
  345.   lpbmi->bmiHeader.biCompression   = BI_RGB;
  346.   lpbmi->bmiHeader.biSizeImage     = 0L;
  347.   lpbmi->bmiHeader.biXPelsPerMeter = 0;
  348.   lpbmi->bmiHeader.biYPelsPerMeter = 0;
  349.   lpbmi->bmiHeader.biClrUsed       = 0;
  350.   lpbmi->bmiHeader.biClrImportant  = 0;
  351.  
  352.   /*
  353.     Initialize the colors
  354.   */
  355.   if (IconDir.ColorCount == 2)
  356.   {
  357.     _fmemcpy((LPSTR) &lpbmi->bmiColors[0], rgb[0], 3);
  358.     _fmemcpy((LPSTR) &lpbmi->bmiColors[1], rgb[7], 3);
  359.   }
  360.   else
  361.   {
  362.     int i;
  363.     for (i = 0;  i < 16;  i++)
  364.       _fmemcpy((LPSTR) &lpbmi->bmiColors[i],   rgb[i], 3);
  365.   }
  366.   GlobalUnlock(IconInfo.hBitmapInfo);
  367.  
  368.   /*
  369.     No undo info yet...
  370.   */
  371.   EnableMenuItem(GetMenu(hWndMain), IDM_UNDO, 
  372.                  MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  373. }
  374.  
  375.  
  376.  
  377.  
  378. /****************************************************************************/
  379. /*                                                                          */
  380. /*                    UTILITY ROUTINES                                      */
  381. /*                                                                          */
  382. /*                                                                          */
  383. /****************************************************************************/
  384.  
  385. /****************************************************************************/
  386. /*                                                                          */
  387. /* Function : ColorCountToPlanes()                                          */
  388. /*                                                                          */
  389. /* Purpose  : Given a number of colors, returns the number of color planes  */
  390. /*            needed to represent those colors (log2(Colors))               */
  391. /*                                                                          */
  392. /* Returns  : The number of planes in the pixmap.                           */
  393. /*                                                                          */
  394. /****************************************************************************/
  395. int PASCAL ColorCountToPlanes(int nClr)
  396. {
  397.   switch (nClr)
  398.   {
  399.     case 2 :  return 1;
  400.     case 8 :  return 3;
  401.     case 16:  return 4;
  402.     default:  return 1;
  403.   }
  404. }
  405.  
  406. /****************************************************************************/
  407. /*                                                                          */
  408. /* Function : SetIconPixel()                                                */
  409. /*                                                                          */
  410. /* Purpose  : Sets the nibble in the pixmap which corresponds to location   */
  411. /*            (x,y) to the passed color.                                    */
  412. /*                                                                          */
  413. /* Returns  : Zippo.                                                        */
  414. /*                                                                          */
  415. /****************************************************************************/
  416. VOID PASCAL SetIconPixel(int x, int y, int iColor)
  417. {
  418.   LPSTR lpBits, lpByte;
  419.   int   nPixelsPerByte = 2;
  420.  
  421.   if (IconInfo.hBitmapBits == NULL)
  422.     return;
  423.  
  424.   /*
  425.     Dereference the pixmap and point to the proper location
  426.   */
  427.   lpBits = GlobalLock(IconInfo.hBitmapBits);
  428.   lpByte = lpBits + ((31-y) * IconDir.Width / nPixelsPerByte) + 
  429.                     (x / nPixelsPerByte);
  430.  
  431.   /*
  432.     Set the left or right nibble, depending if the x value is odd or even.
  433.   */
  434.   if (x & 1)
  435.     *lpByte = (*lpByte & 0xF0) | (BYTE) iColor;
  436.   else
  437.     *lpByte = (*lpByte & 0x0F) | ((BYTE) iColor << 4);
  438.   GlobalUnlock(IconInfo.hBitmapBits);
  439. }
  440.  
  441.  
  442. /****************************************************************************/
  443. /*                                                                          */
  444. /* Function : GetIconPixel()                                                */
  445. /*                                                                          */
  446. /* Purpose  : Reads the pixel at location [x,y].                            */
  447. /*                                                                          */
  448. /* Returns  : The color of the pixel at location [x,y].                     */
  449. /*                                                                          */
  450. /****************************************************************************/
  451. int PASCAL GetIconPixel(int x, int y)
  452. {
  453.   LPSTR lpBits, lpByte;
  454.   int   nPixelsPerByte = 2;
  455.  
  456.   if (IconInfo.hBitmapBits == NULL)
  457.     return 0;
  458.  
  459.   /*
  460.     Dereference the pixmap and point to the proper location
  461.   */
  462.   lpBits = GlobalLock(IconInfo.hBitmapBits);
  463.   lpByte = lpBits + ((31-y) * IconDir.Width / nPixelsPerByte) + 
  464.                     (x / nPixelsPerByte);
  465.  
  466.   /*
  467.     If it's an odd column, get the left nibble, else the right one.
  468.   */
  469.   if (x & 1)
  470.     x = (*lpByte & 0xF0) >> 4;
  471.   else
  472.     x = (*lpByte & 0x0F);
  473.  
  474.   GlobalUnlock(IconInfo.hBitmapBits);
  475.   return x;
  476. }
  477.  
  478.  
  479. /****************************************************************************/
  480. /*                                                                          */
  481. /* Function : IconPlotLine()                                                */
  482. /*                                                                          */
  483. /* Purpose  : This is a callback for the LineDDA(). We can set the          */
  484. /*             pixel at (x,y) to the passed color.                          */
  485. /*                                                                          */
  486. /* Returns  : Zilch.                                                        */
  487. /*                                                                          */
  488. /****************************************************************************/
  489. VOID FAR PASCAL IconPlotLine(int x, int y, LPSTR lpData)
  490. {
  491.   if ((x /= 8) > 31)
  492.     x = 31;
  493.   if ((y /= 8) > 31)
  494.     y = 31;
  495.   SetIconPixel(x, y, LOWORD(((LONG) lpData)));
  496. }
  497.  
  498.  
  499.  
  500. /****************************************************************************/
  501. /*                                                                          */
  502. /* Function : DebugBitmap()                                                 */
  503. /*                                                                          */
  504. /* Purpose  : Dumps a hex representation of the pixmap to the debugging     */
  505. /*            window.                                                       */
  506. /*                                                                          */
  507. /* Returns  : Nada.                                                         */
  508. /*                                                                          */
  509. /****************************************************************************/
  510. #ifdef DEBUG
  511. DebugBitmap(HWND hWnd, HANDLE hBits)
  512. {
  513.   int   x, y;
  514.   LPSTR p;
  515.   char  buf[8];
  516.   HDC   hDC;
  517.   TEXTMETRIC tm;
  518.  
  519.   p = GlobalLock(hBits);
  520.   hDC = GetDC(hWnd);
  521.   GetTextMetrics(hDC, (LPTEXTMETRIC) &tm);
  522.  
  523.   for (y = 0;  y < 32;  y++)
  524.   {
  525.     for (x = 0;  x < 16;  x++)
  526.     {
  527.       sprintf(buf, "%02x ", (unsigned char) *p++);
  528.       TextOut(hDC, x*3 * tm.tmAveCharWidth, y * (tm.tmHeight),
  529.                    (LPSTR) buf, 3);
  530.     }
  531.   }
  532.  
  533.   GlobalUnlock(hBits);
  534.   ReleaseDC(hWnd, hDC);
  535. }
  536. #endif 
  537.